﻿using System.Collections.Generic;
using System.Linq;

namespace LeastSquaresSolver
{
    public class LeastSquares
    {
        /// <summary>
        /// M Coefficient for y = Mx + C
        /// </summary>
        public decimal M { get; private set; }
        /// <summary>
        /// C Coefficient for y = Mx + C
        /// </summary>
        public decimal C { get; private set; }

        /// <param name="points">Known points which are used to calculated coefficients</param>
        public LeastSquares(IEnumerable<Point> points)
        {
            CalculateCoefficients(points);
        }

        /// <summary>
        /// Uses the calculated coefficients to solve Y for inputted X
        /// </summary>
        /// <param name="x">X value to solve for</param>
        /// <returns>Y value (y = Mx + C)</returns>
        public decimal Solve(decimal x)
        {
            return (M * x) + C;
        }

        private void CalculateCoefficients(IEnumerable<Point> points)
        {
            var numPoints = points.Count();
            var sumX = points.Sum(point => point.X);
            var sumY = points.Sum(point => point.Y);
            var sumXX = points.Sum(point => (point.X * point.X));
            var sumXY = points.Sum(point => (point.X * point.Y));
            C = (-sumX * sumXY + sumXX * sumY) / (numPoints * sumXX - sumX * sumX);
            M = (-sumX * sumY + numPoints * sumXY) / (numPoints * sumXX - sumX * sumX);
        }
    }
}
